package struct
{
	
	import flash.utils.Dictionary;
	

	/**
	 * 键、值映射的存储对象。
	 */
	public class HashMap
	{
		/** 个数 */
		private var length:int;
		/** 存储对象 */
		private var content:Dictionary;
		
		public function HashMap(){
			length = 0;
			content = new Dictionary();
		}
		
		
		/**
		 * 共有多少条数据
		 */
		public function size():int{
			return length;
		}
		
		/**
		 * 是否是空的
		 * @return 是空为ture,否为false
		 */
		public function get isEmpty():Boolean{
			return (length==0);
		}
		
		/**
		 * 获取所有的键名
		 * @return 所有键名(Array)
		 */
		public function keys():Array{
			var temp:Array = new Array(length);
			var index:int = 0;
			for(var i:* in content){
				temp[index] = i;
				index ++;
			}
			return temp;
		}
		
		/**
		 * 循环处理所有的数据.
		 * @param func 处理的方法
		 */
		public function eachKey(func:Function):void{
			for(var i:* in content){
				func(i);
			}
		}
		
		/**
		 * 循环处理所有的数据.
		 * @param func 处理的方法
		 */
		public function eachValue(func:Function):void{
			for each(var i:* in content){
				func(i);
			}
		}
		
		/**
		 * 获取所有的数据
		 * @return 所有数据(Array)
		 */
		public function values():Array{
			var temp:Array = new Array(length);
			var index:int = 0;
			for each(var i:* in content){
				temp[index] = i;
				index ++;
			}
			return temp;
		}
		
		/**
		 * 是否包含该数据
		 * @param   value  数据
		 * @return  包含为true,否为false
		 */
		public function containsValue(value:*):Boolean{
			for each(var i:* in content){
				if(i === value){
					return true;
				}
			}
			return false;
		}
		
		/**
		 * 是否包含该键名
		 * @param   key  键名
		 * @return  包含为true,否为false
		 */
		public function containsKey(key:*):Boolean{
			if(content[key] != undefined){
				return true;
			}
			return false;
		}
		
		/**
		 * 根据键名获取数据
		 * 
		 * @param   key 键名.
		 * @return  the 键名映射的数据,无该键返回 null.
		 */
		public function getValue(key:*):*{
			var value:* = content[key];
			if(value != undefined){
				return value;
			}
			return null;
		}
		
		/**
		 * 添加一条数据.
		 * 
		 * @param key 数据的键名.
		 * @param value 映射的数据.
		 * @return 键名对应的数据,如没有该键为 null。
		 */
		public function put(key:*, value:*):*{
			if(key == null){
				throw new ArgumentError("cannot put a value with undefined or null key!");
				return undefined;
			}else if(value == null){
				return remove(key);
			}else{
				var exist:Boolean = containsKey(key);
				if(!exist){
					length++;
				}
				var oldValue:* = getValue(key);
				content[key]=value;
				return oldValue;
			}
		}
		
		/**
		 * 根据键删除数据
		 *
		 * @param  key 要删除的键名.
		 * @return 删除的对象.
		 */
		public function remove(key:*):*{
			var exist:Boolean = containsKey(key);
			if(!exist){
				return null;
			}
			var temp:* = content[key];
			content[key] = null;
			length--;
			return temp;
		}
		
		/**
		 * 清空数据
		 */
		public function clear():void{
			length = 0;
			content = new Dictionary();
		}
		
		/**
		 * 拷贝数据
		 * @return 克隆的数据(HashMap)
		 */
		public function clone():HashMap{
			var temp:HashMap = new HashMap();
			for(var i:* in content){
				temp.put(i, content[i]);
			}
			return temp;
		}
		
		/**
		 * 转换成字符串
		 * @return 字符串
		 */
		public function toString():String{
			var ks:Array = keys();
			var vs:Array = values();
			var temp:String = "HashMap Content:\n";
			for(var i:int=0; i<ks.length; i++){
				temp += ks[i]+" -> "+vs[i] + "\n";
			}
			return temp;
		}		
	}
	
}